package com.milling.business.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.milling.business.BusinessConstants;
import com.milling.business.GlobalVariable;
import com.milling.business.domain.*;
import com.milling.business.mapper.*;
import com.milling.business.service.IWmsConfigHoleService;
import com.milling.business.service.IWmsNeedleCacheService;
import com.milling.common.core.redis.RedisCache;
import com.milling.common.utils.DateUtils;
import com.milling.common.utils.StringUtils;
import com.milling.common.utils.http.HttpUtils;
import com.milling.common.utils.http.WmsApiUtils;
import com.milling.common.utils.modbus.ModbusMasterPoolFactory;
import com.milling.common.utils.modbus.ModbusServiceFactory;
import com.milling.common.utils.modbus.ModbusTcpService;
import com.milling.common.utils.modbus.ModbusTcpServiceImpl;
import com.milling.common.utils.sql.DbUtils;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import org.apache.commons.pool2.ObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.milling.business.service.IWmsTaskInfoService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;

/**
 * 任务工单Service业务层处理
 *
 * @author X
 * @date 2025-02-27
 */
@Service
public class WmsTaskInfoServiceImpl implements IWmsTaskInfoService
{

    private static final Logger logger = LoggerFactory.getLogger(WmsTaskInfoServiceImpl.class);

    // 从参数中读取IP、端口、slaveId和连接池大小
    @Value("${modbus.tcp.host}")
    private String host; // 从配置文件或命令行参数中读取

    @Value("${modbus.tcp.port}")
    private int port; // 从配置文件或命令行参数中读取

    @Value("${modbus.tcp.poolSize}")
    private int poolSize; // 从配置文件或命令行参数中读取

    @Value("${modbus.tcp.slaveId}")
    private int slaveId;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private DbUtils dbUtils;

    @Autowired
    private WmsTxnInfoMapper wmsTxnInfoMapper;

    @Autowired
    private WmsTaskInfoMapper wmsTaskInfoMapper;

    @Autowired
    private WmsCellInfoMapper wmsCellInfoMapper;

    @Autowired
    private WmsConfigSubMapper wmsConfigSubMapper;

    @Autowired
    private WmsNeedleCacheMapper wmsNeedleCacheMapper;

    @Autowired
    private WmsConfigInfoMapper wmsConfigInfoMapper;

    @Autowired
    private IWmsNeedleCacheService wmsNeedleCacheService;

    @Autowired
    private WmsConfigHoleMapper wmsConfigHoleMapper;

    // 获取Modbus服务实例
    private ModbusTcpService modbusTcpService;

    @Autowired
    private WmsConfigSupplyMapper wmsConfigSupplyMapper;

    @Autowired
    private WmsConfigInfoServiceImpl wmsConfigInfoServiceImpl;

    @Autowired
    private WmsConfigHoleServiceImpl wmsConfigHoleService;
    @PostConstruct
    public void init() {
        // 初始化 Modbus 服务
        modbusTcpService = ModbusServiceFactory.getModbusService(host, port, poolSize);
        logger.info("WmsTaskInfoServiceImpl Modbus服务初始化完成 - {}:{}", host, port);

        // 初始化扫码器连接
//        initConnection();
    }
    /**
     * 查询任务工单
     *
     * @param taskId 任务工单主键
     * @return 任务工单
     */
    @Override
    public WmsTaskInfo selectWmsTaskInfoByTaskId(String taskId)
    {
        return wmsTaskInfoMapper.selectWmsTaskInfoByTaskId(taskId);
    }

    /**
     * 查询任务工单列表
     *
     * @param wmsTaskInfo 任务工单
     * @return 任务工单
     */
    @Override
    public List<WmsTaskInfo> selectWmsTaskInfoList(WmsTaskInfo wmsTaskInfo)
    {
        return wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
    }

    /**
     * 新增任务工单
     *
     * @param wmsTaskInfo 任务工单
     * @return 结果
     */
    @Override
    public int insertWmsTaskInfo(WmsTaskInfo wmsTaskInfo)
    {
        wmsTaskInfo.setCreateTime(DateUtils.getNowDate());
        return wmsTaskInfoMapper.insertWmsTaskInfo(wmsTaskInfo);
    }

    /**
     * 修改任务工单
     *
     * @param wmsTaskInfo 任务工单
     * @return 结果
     */
    @Override
    public int updateWmsTaskInfo(WmsTaskInfo wmsTaskInfo)
    {
        wmsTaskInfo.setUpdateTime(DateUtils.getNowDate());
        return wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
    }

    /**
     * 批量删除任务工单
     *
     * @param taskIds 需要删除的任务工单主键
     * @return 结果
     */
    @Override
    public int deleteWmsTaskInfoByTaskIds(String[] taskIds)
    {
        return wmsTaskInfoMapper.deleteWmsTaskInfoByTaskIds(taskIds);
    }

    /**
     * 删除任务工单信息
     *
     * @param taskId 任务工单主键
     * @return 结果
     */
    @Override
    public int deleteWmsTaskInfoByTaskId(String taskId)
    {
        return wmsTaskInfoMapper.deleteWmsTaskInfoByTaskId(taskId);
    }


    @Transactional
    public String processBindDrillinfo(WmsTxnInfo wmsTxnInfo) {
        int returncode = 0;
        String boxcodeRespones = "";
        String jsonString = wmsTxnInfo.getReqBody();
        logger.info("processBindDrillinfo jsonString is " + jsonString);
        JSONObject jsonObject2 = JSONObject.parseObject(jsonString);
        long startTime = System.currentTimeMillis(); // 记录开始时间

        try {

            String macCode = jsonObject2.getString("MacCode");
            String boxId = jsonObject2.getString("box_id");

            wmsTxnInfo.setCreateTime(DateUtils.getNowDate());
            wmsTxnInfo.setMacCode(macCode);
            wmsTxnInfo.setCreateBy("MacCode:"+macCode);
//            wmsTxnInfo.setTxnId(UUID.randomUUID().toString());
            wmsTxnInfo.setUpdateTime(DateUtils.getNowDate());
            wmsTxnInfoMapper.insertWmsTxnInfo(wmsTxnInfo);

            //调用后库接口，询问boxId对应的针盒信息
            // 将后库询问钻针信息接口返回信息 解析JSON字符串
            jsonObject2.put("box_id", boxId);
            String jsonString2 = jsonObject2.toJSONString();
            System.out.println("请求包：" + jsonString2);
            boxcodeRespones = HttpUtils.postData("http://192.168.237.200:5001/RestAPI/QueryDrillinfoByBoxid", jsonString2);
            System.out.println("返回包：" + boxcodeRespones);

            JSONObject jsonObject = JSONObject.parseObject(boxcodeRespones);
//            "Message": "ok", ‘返回信息，ok 为成功

            String message = jsonObject.getString("Message");

            //处理直通 或 缓存库补料
            WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
            wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_3);
/*
            if(1 == 1) {//缓存库补料
                wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_3);
            } else {//借道缓存库直通
                wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_4);
            }
*/
            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_1);
            List<WmsTaskInfo> wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
            if (wmsTaskInfoList.size() > 0) {
                WmsTaskInfo wmsTaskInfoDB = wmsTaskInfoList.get(0);
                wmsTaskInfoDB.setTaskStatus(BusinessConstants.TASK_STATUS_4);
                wmsTaskInfoDB.setBoxCode(boxId);
                wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfoDB);

                String plcAddress = wmsTaskInfoDB.getPlcAddr();
                String plcValue = wmsTaskInfoDB.getPlcValue();

                if("ok".equals(message)) {
                    // 获取参数
                    String drillInfo = jsonObject.getString("m_Drill_Info");
                    Long drillCount = jsonObject.getLong("m_Drill_Count");
                    String drillSize = jsonObject.getString("m_Drill_Size");
                    Long drillGrindCount = jsonObject.getLong("m_Drill_Grind_Count");
                    String drillEdge = jsonObject.getString("m_Drill_Edge");
                    String drillFactory = jsonObject.getString("m_Drill_Factory");
                    String drillType = jsonObject.getString("m_Drill_Type");

                    // 绑定钻针信息的逻辑
                    // 例如：将钻针信息绑定到某个设备或库位
                    // 这里可以根据业务需求编写具体的逻辑

                    // 生成TASK，如果是直通需记录plcAddress及plcValue；在后库来料扫码时，将plcValue写入plcAddress
                    // 根据plcAddress来区分直通 还是 入缓存库
//"503"
//        "555"
                    //处理PLC后续地址信息
                    // 创建连接池
//                    ObjectPool<ModbusMaster> modbusMasterPool = ModbusMasterPoolFactory.createPool(host, port, poolSize);
//                    // 创建ModbusService实例
//                    ModbusTcpService modbusTcpService = new ModbusTcpServiceImpl(modbusMasterPool);

                    if ("553".equals(plcAddress)) {//
                        WmsCellInfo wmsCellInfo2 = new WmsCellInfo();
                        wmsCellInfo2.setCellStatus(BusinessConstants.CELL_STATUS_1);
                        List<WmsCellInfo> wmsCellInfoList = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfo2);
                        if (wmsCellInfoList.size() > 0) {
                            WmsCellInfo wmsCellInfo = wmsCellInfoList.get(0);
                            // 将钻针信息存储到数据库，入缓存库
                            wmsCellInfo.setDrillFactory(drillFactory);
                            wmsCellInfo.setDrillType(drillType);
                            wmsCellInfo.setDrillEdge(drillEdge);
                            wmsCellInfo.setDrillSize(drillSize);
                            wmsCellInfo.setDrillGrindCount(drillGrindCount);
                            wmsCellInfo.setDrillInfo(drillInfo);
                            wmsCellInfo.setDrillCount(drillCount);
                            wmsCellInfo.setCellStatus("1"); // 假设1表示已绑定
                            int result = wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfo);
                            if (result > 0) {
                                returncode = 1;
                                logger.info("钻针信息绑定成功，分配库位: {}", wmsCellInfo.getCellId());
                                // 修复：向PLC写入真正的库位ID，而不是0
                                try {
                                    modbusTcpService.writeHoldingRegister(slaveId, 553, wmsCellInfo.getCellId().intValue());
                                    logger.info("向PLC写入寄存器553，库位ID: {}", wmsCellInfo.getCellId());
                                } catch (ModbusTransportException e) {
                                    logger.error("写入寄存器553失败，库位ID: {}", wmsCellInfo.getCellId(), e);
                                    returncode = 1;
                                }
                            } else {
                                returncode = 2;
                                logger.error("钻针信息绑定失败: {}", jsonObject);
                            }
                        } else {
                            logger.error("没有空余的库位，无法分配");
                            returncode = 3;
                        }
                    } else if("503".equals(plcAddress)) {
                        //直通  之前叫料所记录
                        modbusTcpService.writeHoldingRegister(slaveId, 551, 2);//502清0

                        try {
                            modbusTcpService.writeHoldingRegister(slaveId, new Long(plcAddress).intValue(), new Long(plcValue).intValue());//上料托盘整盒ID 1-16
                            logger.info("写入寄存器地址 503 位置 " + plcValue);
                        } catch (ModbusTransportException e) {
                            returncode = 1;
                            logger.error("写入寄存器地址 503 位置 失败");
                        }
                    }
                } else {
                    returncode = 5;
                    logger.error("调用后库 钻针信息绑定接口失败: {}", jsonObject);
                    //调用后库失败
                }
            }
        } catch (Exception e) {
            logger.error("绑定钻针信息时发生异常: {}", jsonString, e);
//            return AjaxResult.error("绑定钻针信息时发生异常: " + e.getMessage());
        } finally {
            long endTime = System.currentTimeMillis(); // 记录结束时间
            long duration = endTime - startTime; // 计算执行时间
            logger.info("BindDrillinfo executed in {} ms", duration); // 输出执行时间
        }
        return boxcodeRespones;
    }

    public void genWmsTaskInfo(String macCode, String taskType, Long configId, Long configSubId, String drillInfo, String fullType, Integer drillCount, Integer boxId, String feedingHoles) {
        WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
        wmsTaskInfo.setMacCode(macCode);
        wmsTaskInfo.setTaskType(taskType);
        wmsTaskInfo.setConfigId(configId);
        wmsTaskInfo.setConfigSubId(configSubId);
        if(null != boxId) {
            wmsTaskInfo.setBoxId(Integer.toUnsignedLong(boxId));
        }

//        if(BusinessConstants.FULL_TYPE_MIX.equals(fullType)) {
//            wmsTaskInfo.setNeedleId(Integer.toUnsignedLong(boxId));
//        }
        if(StringUtils.isNotEmpty(feedingHoles)) {
            wmsTaskInfo.setFeedingHoles(feedingHoles);
        }

//        wmsTaskInfo.setPlcValue(boxId);//fullType为1，即1-16； 否则1-84
        wmsTaskInfo.setMaterialCount(Integer.toUnsignedLong(drillCount));
//        wmsTaskInfo.setTaskId(java.util.UUID.randomUUID().toString());
        wmsTaskInfo.setUpdateBy(BusinessConstants.GENERATOR_RECORD_AUTHOR);
        wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_1);
        wmsTaskInfo.setFullType(fullType);
        wmsTaskInfo.setCreateTime(DateUtils.getNowDate());

        wmsTaskInfo.setDrillInfo(drillInfo);

        wmsTaskInfoMapper.insertWmsTaskInfo(wmsTaskInfo);
    }

    private WmsNeedleCache calcReturnBoxId() {
        WmsConfigInfo wmsConfigInfo = new WmsConfigInfo();
        wmsConfigInfo.setConfigStatus(BusinessConstants.CONFIG_STATUS_CONFIGING);
        List<WmsConfigInfo> wmsConfigInfos = wmsConfigInfoMapper.selectWmsConfigInfoList(wmsConfigInfo);

        Long configId = 0L;
        if(null == wmsConfigInfos || wmsConfigInfos.size() == 0) {
            wmsConfigInfo.setConfigStatus(BusinessConstants.CONFIG_STATUS_PROCESSING);
//            wmsConfigInfo.setConfigStatus(BusinessConstants.CONFIG_STATUS_UNCONFIG);
            wmsConfigInfos = wmsConfigInfoMapper.selectWmsConfigInfoList(wmsConfigInfo);
        }
        configId = wmsConfigInfos.get(0).getConfigId();

        WmsConfigSub wmsConfigSub = new WmsConfigSub();
        wmsConfigSub.setConfigId(configId);
        List<WmsConfigSub> wmsConfigSubs = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSub);
        String dbInstr = "";
        for (int i = 0; i < wmsConfigSubs.size(); i++) {
            WmsConfigSub wmsConfigSub1 = wmsConfigSubs.get(i);
            JSONObject jsonObject = JSONObject.parseObject(wmsConfigSub1.getMixData());
            // 获取 JSON 对象中的所有键
            for (String key : jsonObject.keySet()) {
                if(StringUtils.isNotEmpty(dbInstr)) {
                    dbInstr = dbInstr + ",'" + key + "'";
                } else {
                    dbInstr = dbInstr + "'" + key + "'";
                }
            }
        }
        //查询不需要使用到的钻针
        if(StringUtils.isNotEmpty(dbInstr)) {
            logger.info("计算回流针盒逻辑");
            dbInstr = "(" + dbInstr + ")";
            dbInstr = "select * from wms_needle_cache where status = '2' and drill_info not in " + dbInstr;
//            DbUtils dbUtils = new DbUtils();
            List<Map<String, Object>> result = dbUtils.executeQuery(dbInstr);

            for (int i = 0; i < result.size(); i++) {
                Map<String, Object> map = result.get(i);
                Integer needle_id = (Integer)map.get("needle_id");
                Long boxId = (new Long(needle_id));
//                if(GlobalVariable.CONFIG_TRAY == 1) {
                if(getTray() == 1) {
                    if(boxId > 42) {
                        WmsNeedleCache wmsNeedleCache = wmsNeedleCacheMapper.selectWmsNeedleCacheByNeedleId(boxId);
                        return wmsNeedleCache;
                    }
                } else {
                    if(boxId <= 42) {
                        WmsNeedleCache wmsNeedleCache = wmsNeedleCacheMapper.selectWmsNeedleCacheByNeedleId(boxId);
                        return wmsNeedleCache;
                    }
                }
            }
            if(result != null && result.size() > 0) {
                Map<String, Object> map = result.get(0);
                Long boxId = (Long)map.get("needle_id");
                WmsNeedleCache wmsNeedleCache = wmsNeedleCacheMapper.selectWmsNeedleCacheByNeedleId(boxId);
                return wmsNeedleCache;
            }
        }
        return null;
    }

    @Transactional
    public void feedingMixV() {
        WmsConfigSub wmsConfigSubQuery = new WmsConfigSub();
        wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_CONFIGING);
        List<WmsConfigSub> wmsConfigSubs = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
        if(null != wmsConfigSubs && wmsConfigSubs.size() > 0) {
            WmsTaskInfo wmsTaskInfoQuery2 = new WmsTaskInfo();
            wmsTaskInfoQuery2.setConfigSubId(wmsConfigSubs.get(0).getConfigSubId());
            wmsTaskInfoQuery2.setFullType(BusinessConstants.FULL_TYPE_MIX);
            wmsTaskInfoQuery2.setTaskStatus(BusinessConstants.TASK_STATUS_1);
            List<WmsTaskInfo> wmsTaskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfoQuery2);
            if (null != wmsTaskInfos && wmsTaskInfos.size() > 0) {
                WmsTaskInfo wmsTaskInfo = wmsTaskInfos.get(0);

                String drillInfo = wmsTaskInfo.getDrillInfo();
                WmsCellInfo wmsCellInfo = new WmsCellInfo();
                wmsCellInfo.setDrillInfo(drillInfo);
                wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_3);
                List<WmsCellInfo> wmsCellInfos = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfo);
                if (null != wmsCellInfos && wmsCellInfos.size() > 0) {

                    //计算补去哪个托盘 calcSupplyNeedleid(wmsConfigSubs.get(0).getConfigSubId())
//                    calcSupplyNeedleid

                    //补散料时，写入PLC地址等信息  XXXXXXXYYYYY//优化补料托盘计算
//                    WmsNeedleCache wmsNeedleCache = new WmsNeedleCache();
//                    wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_1);
//                    List<WmsNeedleCache> wmsNeedleCaches = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCache);
                    WmsNeedleCache wmsNeedleCacheDB = calcSupplyNeedleid(wmsConfigSubs.get(0), drillInfo);
                    int needleId = 0;
//                    if (null != wmsNeedleCaches && wmsNeedleCaches.size() > 0) {
//                        WmsNeedleCache wmsNeedleCacheDB = wmsNeedleCaches.get(0);
                    if(null != wmsNeedleCacheDB) {
                        logger.debug("补料口："+getTray()+"  回流位置: " + wmsNeedleCacheDB.getNeedleId());

                        WmsCellInfo wmsCellInfoDB = wmsCellInfos.get(0);
                        wmsCellInfoDB.setCellStatus(BusinessConstants.CELL_STATUS_4);
                        wmsCellInfoDB.setUpdateTime(new Date());
                        wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfoDB);

                        needleId = wmsNeedleCacheDB.getNeedleId().intValue();
                        wmsNeedleCacheDB.setDrillCount(wmsCellInfoDB.getDrillCount());
                        wmsNeedleCacheDB.setDrillInfo(wmsCellInfoDB.getDrillInfo());
                        wmsNeedleCacheDB.setDrillGrindCount(wmsCellInfoDB.getDrillGrindCount());
                        wmsNeedleCacheDB.setDrillSize(wmsCellInfoDB.getDrillSize());
                        wmsNeedleCacheDB.setDrillType(wmsCellInfoDB.getDrillType());
                        wmsNeedleCacheDB.setDrillFactory(wmsCellInfoDB.getDrillFactory());
                        wmsNeedleCacheDB.setDrillEdge(wmsCellInfoDB.getDrillEdge());
                        wmsNeedleCacheDB.setStatus(BusinessConstants.NEEDLE_STATUS_5);
                        wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCacheDB);

                        wmsTaskInfo.setNeedleId(wmsNeedleCacheDB.getNeedleId());
                        wmsTaskInfo.setBoxId(wmsNeedleCacheDB.getNeedleId());
                        wmsTaskInfo.setCellId(wmsCellInfoDB.getCellId());
                        wmsTaskInfo.setDrillCount(wmsCellInfoDB.getDrillCount());
                        if (needleId > 0 && needleId <= 42) {
                            wmsTaskInfo.setPortId(1L);
                        } else {
                            wmsTaskInfo.setPortId(2L);
                        }
                        wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);//YYYYYY
                        wmsTaskInfo.setUpdateTime(new Date());
                        wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
                        try {
                            if (needleId > 0 && needleId <= 42) {
                                modbusTcpService.writeHoldingRegister(slaveId, 558, 1);
                            } else {
                                modbusTcpService.writeHoldingRegister(slaveId, 558, 2);
                            }
                            modbusTcpService.writeHoldingRegister(slaveId, 559, wmsCellInfoDB.getCellId().intValue());
                            //                        modbusTcpService.writeHoldingRegisters(slaveId, 558, t);
                            modbusTcpService.writeHoldingRegister(slaveId, 510, wmsTaskInfo.getBoxId().intValue());
                        } catch (ModbusTransportException ex) {
                            ex.printStackTrace();
                            logger.info("[PLC]通知料口号失败");
                            // 【新增】PLC通信失败时执行出库回滚
                            try {
                                logger.warn("PLC通信失败，可能导致出库失败，执行状态回滚");
                                rollbackCacheDeliveryFailure();
                            } catch (Exception rollbackException) {
                                logger.error("出库失败回滚时发生异常", rollbackException);
                            }
                        }
                    } else {
                        //回流
                        logger.info("回流任务");
                        wmsNeedleCacheService.sysncNeedleStatus();
                        //计算回流哪个盒子  1-84
                        WmsNeedleCache wmsNeedleCache2 = calcReturnBoxId();
                        logger.debug("回流口："+getTray()+"  回流位置: " + wmsNeedleCache2.getNeedleId());

                        int place = 0;
                        WmsCellInfo wmsCellInfoQuery3 = new WmsCellInfo();
                        wmsCellInfoQuery3.setCellStatus(BusinessConstants.CELL_STATUS_1);
                        List<WmsCellInfo> list2 = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfoQuery3);
//                        WmsNeedleCache wmsNeedleCache2 = wmsNeedleCacheMapper.selectWmsNeedleCacheByNeedleId(boxId);
                        if(null != list2 && list2.size() > 0) {

                            //任务完结时写入
                            place = list2.get(0).getCellId().intValue();
                            WmsCellInfo wmsCellInfo3 = wmsCellInfoMapper.selectWmsCellInfoByCellId(new Long(place));
                            wmsCellInfo3.setDrillInfo(wmsNeedleCache2.getDrillInfo());
                            wmsCellInfo3.setDrillSize(wmsNeedleCache2.getDrillSize());
                            wmsCellInfo3.setDrillType(wmsNeedleCache2.getDrillType());
                            wmsCellInfo3.setDrillEdge(wmsNeedleCache2.getDrillEdge());
                            wmsCellInfo3.setDrillFactory(wmsNeedleCache2.getDrillFactory());
                            wmsCellInfo3.setDrillCount(wmsNeedleCache2.getDrillCount());
                            wmsCellInfo3.setCellStatus(BusinessConstants.CELL_STATUS_2);//监听到机械手动作结束信号再完成
                            wmsCellInfo3.setUpdateTime(new Date());
                            wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfo3);

                            wmsNeedleCache2.setStatus(BusinessConstants.NEEDLE_STATUS_3);
                            wmsNeedleCache2.setUpdateTime(new Date());
                            wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCache2);

                            //将原WmsTaskInfo的状态重置为 待处理，必须先处理配针大盘回流任务
                            WmsTaskInfo wmsTaskInfo1 = new WmsTaskInfo();
                            wmsTaskInfo1.setMacCode(wmsTaskInfo.getMacCode());
                            wmsTaskInfo1.setParentTaskId(wmsTaskInfo.getTaskId());
                            wmsTaskInfo1.setDrillCount(wmsNeedleCache2.getDrillCount());
                            wmsTaskInfo1.setNeedleId(wmsNeedleCache2.getNeedleId());
                            wmsTaskInfo1.setCellId(wmsCellInfo3.getCellId());
                            wmsTaskInfo1.setMaterialCount(wmsNeedleCache2.getDrillCount());
                            wmsTaskInfo1.setConfigSubId(wmsTaskInfo.getConfigSubId());
                            wmsTaskInfo1.setConfigId(wmsTaskInfo.getConfigId());
                            wmsTaskInfo1.setBoxId(wmsNeedleCache2.getNeedleId());
                            wmsTaskInfo1.setFullType(BusinessConstants.FULL_TYPE_MIX);
                            wmsTaskInfo1.setDrillInfo(wmsNeedleCache2.getDrillInfo());
//                            wmsTaskInfo1.setFeedingHoles(wmsTaskInfo.getFeedingHoles());
                            wmsTaskInfo1.setPortId(wmsTaskInfo.getPortId());
                            wmsTaskInfo1.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                            wmsTaskInfo1.setTaskType(BusinessConstants.TASK_TYPE_2);
                            wmsTaskInfo1.setCreateTime(new Date());
                            wmsTaskInfoMapper.insertWmsTaskInfo(wmsTaskInfo1);

                            //将原WmsTaskInfo的状态重置为 待处理，必须先处理配针大盘回流任务
                            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_1);//YYYYYY
                            wmsTaskInfo.setUpdateTime(new Date());
                            wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);

                            // 创建连接池
//                            ObjectPool<ModbusMaster> modbusMasterPool = ModbusMasterPoolFactory.createPool(host, port, poolSize);
//
//                            // 创建ModbusService实例
//                            ModbusTcpService modbusTcpService = new ModbusTcpServiceImpl(modbusMasterPool);
                            try {
                    // 这一段替换下列处理逻辑
                                int returnTray = 1;
                                if(getTray() == 0 || getTray() == 1) {
                                    returnTray = 2;
                                } else if(getTray() == 2) {
                                    returnTray = 1;
                                }

                                /*    20251018 暂时屏蔽
                                int returnTray = 1;
                                if(wmsNeedleCache2.getNeedleId() <= 42) {
                                    returnTray = 1;
                                    if(getTray() == 0 || getTray() == 1) {
                                        modbusTcpService.writeHoldingRegister(slaveId, 508, 2);//切换配针托盘
                                        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 2);
                                    }
                                } else if(getTray() == 0 || wmsNeedleCache2.getNeedleId() <= 84) {
                                    returnTray = 2;
                                    if(getTray() == 2) {
                                        modbusTcpService.writeHoldingRegister(slaveId, 508, 1);//切换配针托盘
                                        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
                                    }
                                }*/
/*
                                if(wmsNeedleCache2.getNeedleId() <= 42) {
                                    returnTray = 1;
                                    if(GlobalVariable.CONFIG_TRAY == 0 || GlobalVariable.CONFIG_TRAY == 1) {
                                        modbusTcpService.writeHoldingRegister(slaveId, 508, 2);//切换配针托盘
                                        GlobalVariable.CONFIG_TRAY = 2;
                                    }
                                } else if(GlobalVariable.CONFIG_TRAY == 0 || wmsNeedleCache2.getNeedleId() <= 84) {
                                    returnTray = 2;
                                    if(GlobalVariable.CONFIG_TRAY == 2) {
                                        modbusTcpService.writeHoldingRegister(slaveId, 508, 1);//切换配针托盘
                                        GlobalVariable.CONFIG_TRAY = 1;
                                    }
                                }
*/

                                modbusTcpService.writeHoldingRegister(slaveId, 517, wmsNeedleCache2.getNeedleId().intValue());//配针托盘整盒ID   1-84
                                modbusTcpService.writeHoldingRegister(slaveId, 555, returnTray);//配针托盘整盒ID
                                modbusTcpService.writeHoldingRegister(slaveId, 556, place);//上料托盘整盒ID   1-1208
                            } catch (ModbusTransportException e) {
                                e.printStackTrace();
                                logger.error("写入寄存器地址 517/555/556 位置 失败");
//                            } finally {
//                                modbusMasterPool.close();
                            }
                        } else {
                            logger.error("缓存立库无空余位，无法回流，此处记录并返回信息，配针机弹出提示信息");
                        }
                    }
                    logger.info("[PLC]通知料口号：" + GlobalVariable.CONFIG_TRAY + "成功");
                } else {
                    logger.error("料号 {} 在缓存库库存不足，请求叫料", drillInfo);
                    WmsApiUtils wmsApiUtils = new WmsApiUtils();
                    JSONObject queryJson = wmsApiUtils.genReqBody(drillInfo, BusinessConstants.DELIVER_PORT_REQUEST_MATERIAL);
                    String response = wmsApiUtils.requestMaterial(queryJson.toJSONString());

                    JSONObject jsonObject2 = JSONObject.parseObject(response);
                    // 提取顶层字段
                    String code = jsonObject2.getString("Code");
                    String message = jsonObject2.getString("Message");
                    if ("ok".equals(message)) {
                        WmsTxnInfo wmsTxnInfo = new WmsTxnInfo();
                        wmsTxnInfo.setReqBody(queryJson.toJSONString());
                        wmsTxnInfo.setResBody(response);
                        wmsTxnInfo.setCreateTime(new Date());

                        wmsTxnInfoMapper.insertWmsTxnInfo(wmsTxnInfo);
                        wmsTaskInfo.setTxnId(wmsTxnInfo.getTxnId());//XXXXX是否需要重新获取，待验证

                        //后库补料，需要新增关联任务信息
                        WmsTaskInfo wmsTaskInfo1 = new WmsTaskInfo();
                        wmsTaskInfo1.setParentTaskId(wmsTaskInfo.getTaskId());
                        wmsTaskInfo1.setTxnId(wmsTxnInfo.getTxnId());
                        wmsTaskInfo1.setDrillCount(wmsTaskInfo.getDrillCount());
                        wmsTaskInfo1.setNeedleId(wmsTaskInfo.getNeedleId());
                        wmsTaskInfo1.setConfigSubId(wmsTaskInfo.getConfigSubId());
                        wmsTaskInfo1.setConfigId(wmsTaskInfo.getConfigId());
                        wmsTaskInfo1.setBoxId(wmsTaskInfo.getBoxId());
                        wmsTaskInfo1.setFeedingHoles(wmsTaskInfo.getFeedingHoles());
                        wmsTaskInfo1.setPortId(wmsTaskInfo.getPortId());
                        wmsTaskInfo1.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                        wmsTaskInfo1.setFullType(BusinessConstants.FULL_TYPE_MIX);
                        wmsTaskInfo1.setTaskType(BusinessConstants.TASK_TYPE_4);
                        wmsTaskInfo1.setCreateTime(new Date());
                        wmsTaskInfoMapper.insertWmsTaskInfo(wmsTaskInfo1);

                        //将原WmsTaskInfo的状态重置为 待处理，必须先处理后库补料缓存库任务
                        wmsTaskInfo.setTxnId(wmsTxnInfo.getTxnId());
                        wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_1);
                        wmsTaskInfo.setUpdateTime(new Date());
                        wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
                    } else {
                        //后续要加工处理
                        logger.info("后库散针补料失败，料号：" + drillInfo + " 原因：" + message);
                        // 【新增】补料失败时执行状态回滚
                        try {
                            rollbackCacheSupplyFailure();
                        } catch (Exception rollbackException) {
                            logger.error("补料失败回滚时发生异常", rollbackException);
                        }
                        throw new RuntimeException("后库散针补料失败，料号：" + drillInfo + " 原因：" + message);
                    }
                }
            }
        }
    }

    public void feedingFull(){
//        if(GlobalVariable.plc501Value == 1 && GlobalVariable.plc502Value == 1){

        if(get501Value() == 1 && get502Value() == 1){
            //执行满盒任务
            WmsConfigSub wmsConfigSubQuery = new WmsConfigSub();
            wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_PRE);//预配针
            List<WmsConfigSub> wmsConfigSubList = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
            if(wmsConfigSubList != null && wmsConfigSubList.size() > 0){
                logger.info("有一个托盘正在预配针状态  CONFIG_STATUS_PRE");
                return;
            }

            wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_CONFIGING);//配针中
            wmsConfigSubList = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
            if(wmsConfigSubList != null && wmsConfigSubList.size() > 0){
                logger.info("有一个托盘正在配针中状态  CONFIG_STATUS_PROCESSING");
                return;
            }

            wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_UNCONFIG);
            wmsConfigSubList = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
            if(wmsConfigSubList != null && wmsConfigSubList.size() > 0) {
                try {
                    WmsConfigSub wmsConfigSub = wmsConfigSubList.get(0);
                    WmsTaskInfo wmsTaskInfoQuery = new WmsTaskInfo();
                    wmsTaskInfoQuery.setTaskStatus(BusinessConstants.TASK_STATUS_1);
                    wmsTaskInfoQuery.setFullType(BusinessConstants.FULL_TYPE_FULL);
                    wmsTaskInfoQuery.setConfigSubId(wmsConfigSub.getConfigSubId());
                    wmsTaskInfoQuery.setTaskType(BusinessConstants.TASK_TYPE_1);
                    List<WmsTaskInfo> taskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfoQuery);
                    if (null != taskInfos && taskInfos.size() > 0) {
                        WmsTaskInfo wmsTaskInfo = taskInfos.get(0);
                        Long boxId = wmsTaskInfo.getBoxId();
                        String fullType = wmsTaskInfo.getFullType();
                        String drillInfos = wmsTaskInfo.getDrillInfo();
                        logger.info("盒子 " + boxId + " 类型: " + fullType + ", 信息: " + drillInfos);

                        //缓存库叫料 - 优先查找空闲位置，然后查找有货位置
                        List<WmsCellInfo> wmsCellInfos = new ArrayList<>();

                        // 首先查找空闲位置
                        WmsCellInfo wmsCellInfoEmpty = new WmsCellInfo();
                        wmsCellInfoEmpty.setCellStatus(BusinessConstants.CELL_STATUS_1); // 空闲
                        List<WmsCellInfo> emptyCells = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfoEmpty);

                        if (emptyCells.size() > 0) {
                            logger.info("找到空闲缓存库位置进行补料，数量: {}", emptyCells.size());
                            wmsCellInfos = emptyCells;
                        } else {
                            // 没有空闲位置时，不应该往有料位置送料，而是等待或报警
                            logger.warn("配针机没有空闲位置，暂停出料等待空闲位置。料号: {}", drillInfos);
                            wmsCellInfos = new ArrayList<>(); // 返回空列表，避免往有料位置送料
                        }

                        if (wmsCellInfos.size() > 0) {
                            logger.info("纯缓存库下料到空闲位置");
                            WmsCellInfo wmsCellInfoDB = wmsCellInfos.get(0);
//                            wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_1);
                            wmsTaskInfo.setCellId(wmsCellInfoDB.getCellId());
                            //PC接收到WCS送整盒到达后，通知PLC取针并放入上料托盘ID号
                            wmsCellInfoDB.setCellStatus(BusinessConstants.CELL_STATUS_4);
                            modbusTcpService.writeHoldingRegister(slaveId, 558, BusinessConstants.PORT_ID_RIGHT.intValue());
                            modbusTcpService.writeHoldingRegister(slaveId, 559, wmsCellInfoDB.getCellId().intValue());
                            modbusTcpService.writeHoldingRegister(slaveId, 503, boxId.intValue());
                            logger.info("[PLC]PC接收到WCS送整盒到达后，通知PLC取针并放入上料托盘第" + boxId + "个盒子");
                            wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfoDB);

//                                 wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);//YYYYYYYYYYYYYXXXX
//                                 wmsTaskInfoService.updateWmsTaskInfo(wmsTaskInfo);
                            wmsTaskInfo.setPortId(BusinessConstants.PORT_ID_RIGHT);
                            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                            wmsTaskInfo.setUpdateTime(new Date());
                            wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
                        } else {
                            // 没有空闲位置时，暂不处理此任务，等待下次处理
                            logger.warn("配针机无空闲位置，跳过任务处理。任务ID: {}, 料号: {}", wmsTaskInfo.getTaskId(), drillInfos);
                        }
                    } else {
                        wmsTaskInfoQuery.setTaskType(BusinessConstants.TASK_TYPE_3);
                        //3拆分成4盒1，先4后1
                        taskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfoQuery);
                        if (null != taskInfos && taskInfos.size() > 0) {
                            //                     for (int i = 0; i < taskInfos.size(); i++) {
                            //                         for (int i = 0; i < taskInfos.size(); i++) {
                            WmsTaskInfo wmsTaskInfo = taskInfos.get(0);
                            Long boxId = wmsTaskInfo.getBoxId();
                            String fullType = wmsTaskInfo.getFullType();
                            String drillInfos = wmsTaskInfo.getDrillInfo();
                            logger.info("盒子 " + boxId + " 类型: " + fullType + ", 信息: " + drillInfos);

                            //缓存库叫料
                            WmsCellInfo wmsCellInfo = new WmsCellInfo();
                            wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_3);
                            wmsCellInfo.setDrillInfo(drillInfos);
                            List<WmsCellInfo> wmsCellInfos = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfo);
                            if (wmsCellInfos.size() > 0) {
                                logger.info("缓存库下料 ");
                                WmsCellInfo wmsCellInfoDB = wmsCellInfos.get(0);
//                            wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_1);
                                wmsTaskInfo.setCellId(wmsCellInfoDB.getCellId());
                                //PC接收到WCS送整盒到达后，通知PLC取针并放入上料托盘ID号
                                wmsCellInfoDB.setCellStatus(BusinessConstants.CELL_STATUS_4);
                                modbusTcpService.writeHoldingRegister(slaveId, 558, BusinessConstants.PORT_ID_RIGHT.intValue());
                                modbusTcpService.writeHoldingRegister(slaveId, 559, wmsCellInfoDB.getCellId().intValue());
                                modbusTcpService.writeHoldingRegister(slaveId, 503, boxId.intValue());
                                logger.info("[PLC]PC接收到WCS送整盒到达后，通知PLC取针并放入上料托盘第"+boxId+"个盒子");
                                wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfoDB);

//                                 wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);//YYYYYYYYYYYYYXXXX
//                                 wmsTaskInfoService.updateWmsTaskInfo(wmsTaskInfo);
                                wmsTaskInfo.setPortId(BusinessConstants.PORT_ID_RIGHT);
                                wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                                wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
                            } else {
                                logger.error("整合补料，缓存库不足料， 拆分任务  ");
//                                wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_3);
                                WmsApiUtils wmsApiUtils = new WmsApiUtils();
                                JSONObject queryJson = wmsApiUtils.genReqBody(drillInfos, BusinessConstants.DELIVER_PORT_REQUEST_MATERIAL);
                                String response = wmsApiUtils.requestMaterial(queryJson.toJSONString());

                                JSONObject jsonObject2 = JSONObject.parseObject(response);
                                // 提取顶层字段
                                String code = jsonObject2.getString("Code");
                                String message = jsonObject2.getString("Message");
                                if("ok".equals(message)) {
                                    WmsTxnInfo wmsTxnInfo = new WmsTxnInfo();
                                    wmsTxnInfo.setReqBody(queryJson.toJSONString());
                                    wmsTxnInfo.setResBody(response);
                                    wmsTxnInfo.setCreateTime(new Date());
                                    wmsTxnInfo.setRemark("整盒后库先到缓存库，再去配针机;管理TASK " + wmsTaskInfo.getTaskId());
                                    wmsTxnInfoMapper.insertWmsTxnInfo(wmsTxnInfo);
                                    //暂时不处理WMSTASKINFO

                                    //后库补料，需要新增关联任务信息
                                    WmsTaskInfo wmsTaskInfo1 = new WmsTaskInfo();
                                    wmsTaskInfo1.setTxnId(wmsTxnInfo.getTxnId());
                                    wmsTaskInfo1.setParentTaskId(wmsTaskInfo.getTaskId());
                                    wmsTaskInfo1.setDrillCount(wmsTaskInfo.getDrillCount());
                                    wmsTaskInfo1.setNeedleId(wmsTaskInfo.getNeedleId());
                                    wmsTaskInfo1.setConfigSubId(wmsTaskInfo.getConfigSubId());
                                    wmsTaskInfo1.setConfigId(wmsTaskInfo.getConfigId());
                                    wmsTaskInfo1.setBoxId(wmsTaskInfo.getBoxId());
                                    wmsTaskInfo1.setFeedingHoles(wmsTaskInfo.getFeedingHoles());
                                    wmsTaskInfo1.setPortId(wmsTaskInfo.getPortId());
                                    wmsTaskInfo1.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                                    wmsTaskInfo1.setTaskType(BusinessConstants.TASK_TYPE_4);
                                    wmsTaskInfo1.setFullType(BusinessConstants.FULL_TYPE_FULL);
                                    wmsTaskInfo1.setCreateTime(new Date());
                                    wmsTaskInfoMapper.insertWmsTaskInfo(wmsTaskInfo1);

                                    //将原WmsTaskInfo的状态重置为 待处理，必须先处理后库补料缓存库任务
                                    wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_1);
                                    wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_1);
                                    wmsTaskInfo.setTxnId(wmsTxnInfo.getTxnId());
                                    //此处需要去掉parentTaskId，不能互相parentTaskId
                                    wmsTaskInfo.setParentTaskId(wmsTaskInfo1.getTaskId());
                                    wmsTaskInfo.setUpdateTime(new Date());
                                    wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);

//                                    wmsTaskInfo.setTxnId(wmsTxnInfo.getTxnId());//XXXXX是否需要重新获取，待验证
                                    //后库下料，需等扫码器扫码成功才写入PLC地址
                                } else {
                                    //后续要加工处理
                                    logger.info("后库盒料补整失败，原因：" + message);
                                    // 【新增】补料失败时执行状态回滚
                                    try {
                                        rollbackCacheSupplyFailure();
                                    } catch (Exception rollbackException) {
                                        logger.error("补料失败回滚时发生异常", rollbackException);
                                    }
                                    throw new RuntimeException("后库盒料补整失败，原因：" + message);
                                }
                            }
//                            wmsTaskInfo.setPortId(BusinessConstants.PORT_ID_RIGHT);
//                            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
//                            wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
                        } else {
                            logger.info("满盒任务配置完成，开始配针");
                            // 创建连接池
                            modbusTcpService.writeHoldingRegister(slaveId, 505, 1);
                            logger.info("[PC]PC通知PLC，整个上料区的整盒配置已经完毕,可以进入中间位置进行配针");
                            wmsConfigSub.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_PRE);
                            wmsConfigSubMapper.updateWmsConfigSub(wmsConfigSub);
                        }
                    }

                } catch (ModbusTransportException ex) {
                    ex.printStackTrace();
                    logger.error("[PLC]PC接收到WCS送整盒到达后，通知PLC取针并放入上料托盘时失败");
                    // 【新增】PLC通信失败时执行出库回滚
                    try {
                        logger.warn("整盒出库PLC通信失败，可能导致出库失败，执行状态回滚");
                        rollbackCacheDeliveryFailure();
                    } catch (Exception rollbackException) {
                        logger.error("出库失败回滚时发生异常", rollbackException);
                    }
//                    logger.info("[PLC]PC接收到WCS送整盒到达后，通知PLC取针并放入上料托盘第"+boxId+"个盒子时 失败");
                }

            } else {
                logger.error("暂时没有运行中的配针任务，请启动配针任务");
            }
        }
    }

    @Override
    @Transactional
    public void write505() {
        WmsConfigSub wmsConfigSubQuery = new WmsConfigSub();
        wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_UNCONFIG);
        List<WmsConfigSub> wmsConfigSubList = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
        if(wmsConfigSubList != null && wmsConfigSubList.size() > 0) {
            WmsConfigSub wmsConfigSub = wmsConfigSubList.get(0);
            WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
            wmsTaskInfo.setFullType(BusinessConstants.FULL_TYPE_FULL);
            List<WmsTaskInfo> taskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
//            ModbusUtil modbusUtil = new ModbusUtil(host, port);
            if (null != taskInfos && taskInfos.size() > 0) {
                WmsTaskInfo wmsTaskInfo1 = taskInfos.get(0);
                wmsTaskInfo1.setTaskStatus(BusinessConstants.TASK_STATUS_4);
                wmsTaskInfo1.setUpdateTime(new Date());
                wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo1);
            } else {
                logger.info("满盒任务配置完成，开始配针2");
                try {
                    // 创建连接池
                    modbusTcpService.writeHoldingRegister(slaveId, 505, 1);
                    logger.info("[PC]PC通知PLC，整个上料区的整盒配置已经完毕,可以进入中间位置进行配针");
                    wmsConfigSub.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_PRE);
                    wmsConfigSubMapper.updateWmsConfigSub(wmsConfigSub);
                } catch (ModbusTransportException ex) {
                    ex.printStackTrace();
                }

            }

            feedingFull();
        }
    }

    @Override
    public void process511() {
        //配针托盘继续补料
        // 创建连接池
//        ObjectPool<ModbusMaster> modbusMasterPool = ModbusMasterPoolFactory.createPool(host, port, poolSize);
//
//        // 创建ModbusService实例
//        ModbusTcpService modbusTcpService = new ModbusTcpServiceImpl(modbusMasterPool);
        WmsConfigSub wmsConfigSub = new WmsConfigSub();
        wmsConfigSub.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_CONFIGING);
        List<WmsConfigSub> wmsConfigSubs = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSub);

        if (null != wmsConfigSubs && wmsConfigSubs.size() > 0) {
            wmsConfigSub = wmsConfigSubs.get(0);
        }

        WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
        wmsTaskInfo.setConfigSubId(wmsConfigSub.getConfigSubId());
        wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
        wmsTaskInfo.setFullType(BusinessConstants.FULL_TYPE_MIX);
        wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_1);
        List<WmsTaskInfo> wmsTaskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
        Map<String, Integer> addrMap = new HashMap<>();
//        int feedingTray = 1;
        //单任务处理
        if (wmsTaskInfos != null && wmsTaskInfos.size() > 0) {
//        for (int i = 0; i < wmsTaskInfos.size(); i++) {
            WmsTaskInfo wmsTaskInfo1 = wmsTaskInfos.get(0);
            String feedingHoleString = wmsTaskInfos.get(0).getFeedingHoles();
            String[] feedingHoleArray = feedingHoleString.split(",");
            int needleId = wmsTaskInfo1.getBoxId().intValue();

            WmsNeedleCache wmsNeedleCache = wmsNeedleCacheMapper.selectWmsNeedleCacheByNeedleId(wmsTaskInfo1.getBoxId());
            wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_2);
            wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCache);
            for (int j = 0; j < feedingHoleArray.length; j++) {
                int holeId = Integer.parseInt(feedingHoleArray[j].trim());
                addrMap.put(""+(4999+holeId), needleId);
//AAA                    modbusTcpService.writeHoldingRegister(slaveId, (4999 + holeId), needleId);
            }
            addrMap.put(""+(4699+needleId), wmsTaskInfo1.getDrillCount().intValue());
//AAA                modbusTcpService.writeHoldingRegister(slaveId, (4699+needleId), wmsTaskInfo1.getDrillCount().intValue());

            //将当前任务状态改为已完成
            wmsTaskInfo1.setTaskStatus(BusinessConstants.TASK_STATUS_4);
            wmsTaskInfo1.setUpdateTime(new Date());
            wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo1);
        }

        wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_1);
        wmsTaskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);

        try {
            Iterator<Map.Entry<String, Integer>> iterator = addrMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Integer> entry = iterator.next();
                String addr = entry.getKey();
                int value = entry.getValue();
                modbusTcpService.writeHoldingRegister(slaveId, new Integer(addr), value);
//                logger.info("addr:" + addr + " value:" + value);
            }


            //处理补料的孔位数据
            WmsConfigHole wmsConfigHoleQuery = new WmsConfigHole();
            wmsConfigHoleQuery.setConfigSubId(wmsConfigSub.getConfigSubId());
            List<WmsConfigHole> wmsConfigHoles = wmsConfigHoleMapper.selectWmsConfigHoleList(wmsConfigHoleQuery);

//            Iterator<Map.Entry<String, Integer>> iterator = addrMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Integer> entry = iterator.next();
                String addr = entry.getKey();
                int value = entry.getValue();
                int addInt = Integer.parseInt(addr) - 5000;
//                WmsConfigHole wmsConfigHole = wmsConfigHoles.get(value);
                WmsConfigHole wmsConfigHole = wmsConfigHoles.get(addInt);
                wmsConfigHole.setDrillStatus("" + value);
                wmsConfigHole.setUpdateTime(new Date());
                wmsConfigHoleMapper.updateWmsConfigHole(wmsConfigHole);
            }

            if(null != wmsTaskInfos && wmsTaskInfos.size() > 0) {
                Thread.sleep(50);

                //判断是否需要切托盘后再补料
                /*Boolean bFlag = wmsConfigInfoServiceImpl.mixHalf(wmsConfigSub.getConfigSubId());
                if(bFlag) {//需要切托盘后继续补料
                    try {
                        if (getTray() == 1) {
                            modbusTcpService.writeHoldingRegister(slaveId, 508, 2);//切换配针托盘
                            redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 2);
                        } else if (getTray() == 2) {
                            modbusTcpService.writeHoldingRegister(slaveId, 508, 1);//切换配针托盘
                            redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
                        }
                    } catch (ModbusTransportException e) {
                        e.printStackTrace();
                        logger.error("补料过半，切托盘 失败");
                    }
                }*/

                feedingMixV();
            } else {
                modbusTcpService.writeHoldingRegister(slaveId, 513, 1);
            }

//            modbusTcpService.writeHoldingRegister(slaveId, 511, 0);
//            wmsTaskInfoService.feedingMixV();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void process512() {
        // 创建连接池
//        ObjectPool<ModbusMaster> modbusMasterPool = ModbusMasterPoolFactory.createPool(host, port, poolSize);
//
//        // 创建ModbusService实例
//        ModbusTcpService modbusTcpService = new ModbusTcpServiceImpl(modbusMasterPool);
        try {
            WmsTaskInfo wmsTaskInfoQuery = new WmsTaskInfo();
            wmsTaskInfoQuery.setFullType(BusinessConstants.FULL_TYPE_MIX);
            wmsTaskInfoQuery.setTaskStatus(BusinessConstants.TASK_STATUS_2);
            List<WmsTaskInfo> wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfoQuery);
            if(null != wmsTaskInfoList && wmsTaskInfoList.size() > 0) {
                WmsTaskInfo wmsTaskInfo = wmsTaskInfoList.get(0);
                Long needleId = wmsTaskInfo.getNeedleId();
                if(null != needleId && needleId > 0 && needleId <= 42) {
                    if(getTray() == 2) {
                        modbusTcpService.writeHoldingRegister(slaveId, 508, 1);
                        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
//                        GlobalVariable.CONFIG_TRAY = 1;
                        logger.info( "PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成，切左配针");
                    }
                } else if(null != needleId && needleId > 42 && needleId <= 84) {
                    if(getTray() == 1) {
                        modbusTcpService.writeHoldingRegister(slaveId, 508, 2);
                        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 2);
//                        GlobalVariable.CONFIG_TRAY = 2;
                        logger.info("PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成，切右配针");
                    }
                } else {
                    modbusTcpService.writeHoldingRegister(slaveId, 512, 0);
                    logger.info("PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成，纯清0");
                }
                //单任务处理
                //                        break;
            } else {
                wmsTaskInfoQuery.setTaskStatus(BusinessConstants.TASK_STATUS_1);
                wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfoQuery);
                if(null == wmsTaskInfoList || wmsTaskInfoList.size() <= 0) {
                    int value514 = modbusTcpService.readHoldingRegister(slaveId, 514);
                    if( value514 == 0) {//当前配针托盘是否全部配置OK 标志
                        if (getTray() == 1) {
                            modbusTcpService.writeHoldingRegister(slaveId, 508, 2);
                            redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 2);
                            logger.info("PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成");
                        } else {
                            modbusTcpService.writeHoldingRegister(slaveId, 508, 1);
                            redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
                            logger.info("PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成");
                        }
                    }
                    modbusTcpService.writeHoldingRegister(slaveId, 512, 0);
                }

            }
        } catch (Exception e) {
            logger.info("PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成 异常");
            e.printStackTrace();
        }
    }

    @Override
    @Transactional
    public void write800() {
        WmsConfigSub wmsConfigSubQuery = new WmsConfigSub();
        wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_PRE);
        List<WmsConfigSub> wmsConfigSubList = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
        if (null != wmsConfigSubList && wmsConfigSubList.size() > 0) {
            WmsConfigSub wmsConfigSub = wmsConfigSubList.get(0);
            //匹配配针托盘 和 散针配针数据

            Map leftTray = new HashMap();
            Map rightTray = new HashMap();
            boolean feedingMixFlag = false;

            // 创建连接池
//            ObjectPool<ModbusMaster> modbusMasterPool = ModbusMasterPoolFactory.createPool(host, port, poolSize);
//            try {

            // 创建ModbusService实例
//                ModbusTcpService modbusTcpService = new ModbusTcpServiceImpl(modbusMasterPool);

            Map<String, Integer> fullMap = new HashMap();
            Map<String, Integer> mixMap = new HashMap();

            // 给满盒孔位设90
            String fullDataString = wmsConfigSub.getFullData();
            JSONObject fullObject = JSONObject.parseObject(fullDataString);
            for (String key : fullObject.keySet()) {//料号数量
                String boxArray = fullObject.get(key).toString();
                boxArray = boxArray.replace("[", "").replace("]", "");
                String[] boxArray1 = boxArray.split(",");
                for (int i = 0; i < boxArray1.length; i++) {//缺失针盒数
                    fullMap.put((""+boxArray1[i]).trim(), 90);
                }
            }

            String mixDataString = wmsConfigSub.getMixData();
            Map<String, List<String>> nonFullBoxMaterialBoxNumbers =  parseMixData(mixDataString);
            Iterator<Map.Entry<String, List<String>>> iterator = nonFullBoxMaterialBoxNumbers.entrySet().iterator();


            List<Map> needleList = wmsNeedleCacheMapper.selectNeedleStock(new WmsNeedleCache());
            Map<String, Long> needleMap = new HashMap<>();
            for (Map<String, Long> tmpmap : needleList) {
                needleMap.putAll(tmpmap);
                logger.info(tmpmap.toString());
                Iterator<Map.Entry<String, Long>> iteratorTmp = tmpmap.entrySet().iterator();
                logger.info("iteratorTmp " + iteratorTmp);
                //                    while (iteratorTmp.hasNext()) {
                //                        Map.Entry<String, BigDecimal> entry = iteratorTmp.next();
                //                        String key = entry.getKey();
                //                        int value = ((BigDecimal) entry.getValue()).intValue();
                //                        needleMap.put(key, new Long(value));
                //                        BigDecimal value = (BigDecimal) entry.getValue();
                //                        logger.info(key + " || " + value);
                //                    }
            }

            //                wmsNeedleCacheService.syncNeeldStatus();
            while (iterator.hasNext()) {
                Map.Entry<String, List<String>> entry = iterator.next();
                String drillinfo = entry.getKey();
                String holestring = entry.getValue().toString();
                String[] holes = holestring.substring(1, holestring.length() - 1).split(",");

                WmsNeedleCache wmsNeedleCache = new WmsNeedleCache();
                wmsNeedleCache.setDrillInfo(drillinfo);
                wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_2);
                List<WmsNeedleCache> wmsNeedleCaches = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCache);
                int tempInteger = 0;
                int[] drillCountArray = new int[wmsNeedleCaches.size()];
                Long[] needleIdArray = new Long[wmsNeedleCaches.size()];
                for (int i = 0; i < wmsNeedleCaches.size(); i++) {
                    WmsNeedleCache wmsNeedleCache1 = wmsNeedleCaches.get(i);
                    if (null != wmsNeedleCache1.getDrillCount()) {
                        drillCountArray[i] = wmsNeedleCache1.getDrillCount().intValue();
                        needleIdArray[i] = wmsNeedleCache1.getNeedleId();
                        tempInteger = tempInteger + wmsNeedleCache1.getDrillCount().intValue();
                    }
                    logger.info("料号"+drillinfo+"缓存库第" + (i+1) + "个" + wmsNeedleCache1.getDrillInfo() + "的针数" + wmsNeedleCache1.getDrillCount());
                }
                logger.info("料号"+drillinfo+"缓存库总孔位" + tempInteger);
                logger.info("总盘数" + wmsNeedleCaches.size());

                int cacheCount = 0;
                cacheCount = tempInteger;
                //                    String tempDrillinfo = "";

    /*
                if(null != needleMap.get(drillinfo)) {
                    tempInteger = ((Long)needleMap.get(drillinfo)).intValue();
                    cacheCount = tempInteger;
                }
    */

                //                    Integer tempInteger = redisCache.getCacheObject(drillinfo + "-COUNT");
                // 如果读取的数据类型不正确，可以尝试使用 JSON 反序列化

                int balanceCount = 0;
                int okCount = holes.length;
                if(cacheCount < holes.length) {
                    balanceCount = holes.length - cacheCount;
                    okCount = cacheCount;
                }
    /*
                WmsNeedleCache wmsNeedleCache = new WmsNeedleCache();
                wmsNeedleCache.setDrillInfo(drillinfo);
                wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_2);
                List<WmsNeedleCache> wmsNeedleCaches = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCache);
    */
                int j = 0;
                int settingCount = 0;
                for (int i = 0; i < okCount; i++) {
                    String hole = holes[i];
                    if(StringUtils.isNotEmpty(hole)) {
                        hole = hole.trim();
                    }
                    if(wmsNeedleCaches.size() == 0) {
                        //20250421 YYYYYYYYYYYYYYY
                        logger.error("未找到符合条件的针号信息，请检查：" + drillinfo);
                    }
                    Long needleId = new Long(0);
                    try {
                        int needleidPlcCount = drillCountArray[j];
                        needleId = needleIdArray[j];
                        //                            logger.info("这个盒子可以配针 " + needleidPlcCount + " 支");
                        if (i <= (settingCount + needleidPlcCount)) {
                            if (needleId.intValue() <= 42) {
                                leftTray.put("" + needleId, hole);
                            } else {
                                rightTray.put("" + needleId, hole);
                            }
                            //正常是需要要更新状态的，但现在以配针为主，所以先注释掉
                            //                                wmsNeedleCache1.setStatus(BusinessConstants.NEEDLE_STATUS_6);
                            //                                wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCache1);
                            //                            } else {
                        }
                        if(i == (settingCount + needleidPlcCount)) {
                            settingCount = settingCount + drillCountArray[j];
                            j++;
                        }
                        //                            mixMap.put(""+(4999 + Integer.parseInt(hole)), wmsNeedleCache1.getNeedleId().intValue());
                        mixMap.put(""+(4999 + Integer.parseInt(hole)), needleIdArray[j].intValue());
                        //AA                            modbusTcpService.writeHoldingRegister(slaveId, 4999 + Integer.parseInt(hole.trim()), needleId.intValue());
                        //                            logger.info("[PC]PC通知PLC，配针托盘" + drillinfo + "的" + hole + "号孔下料完毕，可以进行配针");
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.error("[PC]PC通知PLC，配针托盘" + drillinfo + "的" + hole + "号孔下料完毕，可以进行配针异常", e);
                        logger.error("cacheCount is异常 " + cacheCount);
                        logger.error("okCount is异常 " + okCount);
                        logger.error("balanceCount is异常 " + balanceCount);
                        logger.error("j is异常 " + j);
                        logger.error("wmsNeedleCaches.size is异常 " + wmsNeedleCaches.size());
                        logger.error("drillinfo is异常 " + drillinfo);
                        logger.error("holestring is异常 " + holestring);
                    }
                }
                if(balanceCount > 0) {
                    feedingMixFlag = true;
                    String balanceString = "";
                    //                        String[] balanceStrings = new String[holestring.split(",").length / 50];
                    for (int i = cacheCount; i < holes.length; i++) {
                        String hole = holes[i];
                        if(StringUtils.isNotEmpty(hole)) {
                            hole = hole.trim();
                        }
                        if(StringUtils.isNotEmpty(balanceString)) {
                            balanceString = balanceString + "," + hole;
                        } else {
                            balanceString = hole;
                        }
                        mixMap.put(""+(4999 + new Integer(hole)), 100);
                        //AA                            modbusTcpService.writeHoldingRegister(slaveId, 4999 + Integer.parseInt(hole.trim()), 100);
                    }
                    //缓存库针盒出库，补料配针机
                    //                        genWmsTaskInfo("D001", BusinessConstants.TASK_TYPE_1, wmsConfigSub.getConfigId(), wmsConfigSub.getConfigSubId(), drillinfo, BusinessConstants.FULL_TYPE_MIX, balanceCount, null, balanceString);
                    String[] balanceArray = converFeedingHolesToArray(balanceString);
                    for (int i = 0; i < balanceArray.length; i++) {
                        String feedingHoles = balanceArray[i];
                        genWmsTaskInfo("D001", BusinessConstants.TASK_TYPE_1, wmsConfigSub.getConfigId(), wmsConfigSub.getConfigSubId(), drillinfo, BusinessConstants.FULL_TYPE_MIX, balanceCount, null, feedingHoles);
                    }
                }
            }

            int trayValue = 1;
            if(leftTray.size() > 0) {
                if(rightTray.size() > 0) {
                    if(leftTray.size() > 0 && rightTray.size() > 0) {
                        if (leftTray.size() > rightTray.size()) {
                            //配左托盘
                            trayValue = 2;
                            //                                GlobalVariable.CONFIG_TRAY = 1;
                            redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
                        } else {
                            //配右托盘
                            trayValue = 1;
                            //                                GlobalVariable.CONFIG_TRAY = 2;
                            redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 2);
                        }
                    }
                } else {
                    //                        GlobalVariable.CONFIG_TRAY = 1;
                    redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
                }
            } else if(rightTray.size() > 0) {
                trayValue = 1;
                //                    GlobalVariable.CONFIG_TRAY = 2;
                redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 2);
            } else {
                //                    GlobalVariable.CONFIG_TRAY = 1;
                redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
            }
            try {

                /// ///////////////// 等 1 分钟代码逻辑
                // 定义批量写入的大小
                int batchSize = 100; // 每次写入 100 个寄存器

// 初始化寄存器数组，从 5000 到 5799，共 800 个寄存器
                short[] registerValues = new short[800];

// 填充寄存器数组，默认值为 0
                Arrays.fill(registerValues, (short) 0);

// 将 fullMap 的数据写入寄存器数组
                for (Map.Entry<String, Integer> entry : fullMap.entrySet()) {
                    String addr = entry.getKey();
                    int value = entry.getValue();
                    int index = Integer.parseInt(addr); // 计算相对于 5000 的偏移量
                    for (int i = 0; i < 50; i++) {
                        registerValues[index + i] = (short) value;
                    }
                }

// 将 mixMap 的数据写入寄存器数组
                for (Map.Entry<String, Integer> entry : mixMap.entrySet()) {
                    String addr = entry.getKey();
                    int value = entry.getValue();
                    int index = Integer.parseInt(addr) - 5000; // 计算相对于 5000 的偏移量
                    registerValues[index] = (short) value;
                }

// 分批次写入寄存器
                int startOffset = 5000; // 起始地址
                for (int i = 0; i < registerValues.length; i += batchSize) {
                    int end = Math.min(i + batchSize, registerValues.length);
                    short[] batchValues = Arrays.copyOfRange(registerValues, i, end);
                    boolean success = false;
                    int retryCount = 0;

                    // 重试逻辑
                    while (!success && retryCount < 3) {
                        try {
                            modbusTcpService.writeHoldingRegisters(slaveId, startOffset + i, batchValues);
                            logger.info("批量写入寄存器成功，起始地址: {}, 数量: {}", startOffset + i, batchValues.length);
                            success = true; // 写入成功，退出循环
                        } catch (ModbusTransportException e) {
                            retryCount++;
                            logger.error("批量写入寄存器失败，起始地址: {}, 数量: {}，重试次数: {}", startOffset + i, batchValues.length, retryCount, e);
                            if (retryCount >= 3) {
                                logger.error("批量写入寄存器失败，达到最大重试次数，起始地址: {}, 数量: {}", startOffset + i, batchValues.length);
                            }
                        }
                    }
                }


                //处理800个孔位数据
                WmsConfigHole wmsConfigHoleQuery = new WmsConfigHole();
                wmsConfigHoleQuery.setConfigSubId(wmsConfigSub.getConfigSubId());
                List<WmsConfigHole> wmsConfigHoles = wmsConfigHoleMapper.selectWmsConfigHoleList(wmsConfigHoleQuery);

                for (int i = 0; i < registerValues.length; i ++) {
                    short oneValue = registerValues[i];
                    if(oneValue > 0) {
                        WmsConfigHole wmsConfigHole = wmsConfigHoles.get(i);
                        wmsConfigHole.setDrillStatus("" + oneValue);
                        wmsConfigHole.setUpdateTime(new Date());
                        wmsConfigHoleMapper.updateWmsConfigHole(wmsConfigHole);
                    }
                }

/*
                Iterator<Map.Entry<String, Integer>> iterator2 = fullMap.entrySet().iterator();
                while (iterator2.hasNext()) {
                    Map.Entry<String, Integer> entry = iterator2.next();
                    String addr = entry.getKey();
                    int value = entry.getValue();
                    for (int i = 0; i < 50; i++) {
                        modbusTcpService.writeHoldingRegister(slaveId, (5000+((new Integer(addr)-1)*50)) + i, value);
//                        logger.info("addrFULL:" + ((5000+new Integer(addr)*50)+i) + " value:" + value);
                    }
                }

                Iterator<Map.Entry<String, Integer>> iterator3 = mixMap.entrySet().iterator();
                while (iterator3.hasNext()) {
                    Map.Entry<String, Integer> entry = iterator3.next();
                    String addr = entry.getKey();
                    int value = entry.getValue();
                    modbusTcpService.writeHoldingRegister(slaveId, new Integer(addr), value);
//                    logger.info("addr:" + addr + " value:" + value);
                }
*/

                /// ////////////////
                modbusTcpService.writeHoldingRegister(slaveId, 509, 1);
//                    modbusTcpService.writeHoldingRegister(slaveId, 508, GlobalVariable.CONFIG_TRAY);
                modbusTcpService.writeHoldingRegister(slaveId, 508, getTray());
            } catch (ModbusTransportException e) {
                logger.error("左右托盘选择/可以开始配针 异常M");
                e.printStackTrace();
            } catch (Exception e) {
                logger.error("左右托盘选择/可以开始配针 异常E");
                e.printStackTrace();
            }
            wmsConfigSub.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_CONFIGING);
            wmsConfigSubMapper.updateWmsConfigSub(wmsConfigSub);
            if(feedingMixFlag) {
                feedingMixV();
            }
        }
    }

    private String[] converFeedingHolesToArray(String str) {
        // 将字符串按逗号分割成数组
        String[] elements = str.split(",");

        // 计算需要多少个子数组
        int chunkSize = 50;
        int numberOfChunks = (int) Math.ceil((double) elements.length / chunkSize);

        // 创建结果数组
        String[] result = new String[numberOfChunks];

        // 填充结果数组
        for (int i = 0; i < numberOfChunks; i++) {
            int start = i * chunkSize;
            int end = Math.min(start + chunkSize, elements.length);

            // 将子数组拼接成字符串
            StringBuilder sb = new StringBuilder();
            for (int j = start; j < end; j++) {
                if (j > start) {
                    sb.append(",");
                }
                sb.append(elements[j]);
            }
            result[i] = sb.toString();
        }

        // 输出结果
//        for (int i = 0; i < result.length; i++) {
//            System.out.println(result[i]);
//        }
        return result;
    }

    private Map<String, List<String>> parseMixData(String mixData) {
        JSONObject jsonObject = JSONObject.parseObject(mixData);
        Map<String, List<String>> map = new HashMap<>();

        for (String key : jsonObject.keySet()) {
            JSONArray jsonArray = jsonObject.getJSONArray(key);
            List<String> stringList = jsonArray.stream()
                    .map(Object::toString)
                    .collect(Collectors.toList());
            map.put(key, stringList);
        }
        return map;
    }

    public void process554() {//回流
        WmsCellInfo wmsCellInfo = new WmsCellInfo();
        wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_2);
        List<WmsCellInfo> list = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfo);
        if(list != null && list.size() > 0) {
            //后库来料入库
//            for (int i = 0; i < list.size(); i++) {
            wmsCellInfo = list.get(0);
            wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_3);
            wmsCellInfo.setUpdateTime(new Date());
            wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfo);
//            }
        }

        //配针机回流入库
        WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
        wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
        wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_2);
        List<WmsTaskInfo> wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
        if (wmsTaskInfoList.size() > 0) {
            wmsTaskInfo = wmsTaskInfoList.get(0);
            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_4);
            wmsTaskInfo.setUpdateTime(new Date());
            wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
        }

        WmsNeedleCache wmsNeedleCache = new WmsNeedleCache();
        wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_3);
        List<WmsNeedleCache> wmsNeedleCaches = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCache);
        for (int i = 0; i < wmsNeedleCaches.size(); i++) {
            wmsNeedleCache = wmsNeedleCaches.get(i);
            wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_1);
            wmsNeedleCache.setUpdateTime(new Date());
            wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCache);
        }

        feedingMixV();
    }

    public void process557() {//入料
        // 【新增】在处理入料前，检查是否有长时间卡住的缓存库位
        try {
            checkAndRollbackStuckedCells();
        } catch (Exception e) {
            logger.error("检查卡住库位时发生异常", e);
        }

        WmsCellInfo wmsCellInfo = new WmsCellInfo();
        wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_2);
        List<WmsCellInfo> list = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfo);
        if(list != null && list.size() > 0) {
            //后库来料入库
//            for (int i = 0; i < list.size(); i++) {
            wmsCellInfo = list.get(0);
            wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_3);
            wmsCellInfo.setUpdateTime(new Date());
            wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfo);
//            }
        } else {
            // 【新增】检查是否存在长时间处于入库中状态的库位，可能是补料失败导致的
            checkAndRollbackStuckedCells();
        }

        int address600V = 0;
        try {
            address600V = modbusTcpService.readHoldingRegister(slaveId, 600);//缓存库补料
            logger.info("读取D600地址值: {}", address600V);
        } catch (ModbusTransportException e) {
            logger.error("读取D600地址失败", e);
            return;
        }

        if(address600V == 2) {
            logger.info("D600=2，开始处理补料逻辑");
            WmsConfigInfo wmsConfigInfo = new WmsConfigInfo();
            wmsConfigInfo.setSupplyStatus(BusinessConstants.SUPPLY_STATUS_2);//补料中的配方
            List<WmsConfigInfo> wmsConfigInfoList = wmsConfigInfoMapper.selectWmsConfigInfoList(wmsConfigInfo);

            if(wmsConfigInfoList != null && wmsConfigInfoList.size() > 0) {
                wmsConfigInfo = wmsConfigInfoList.get(0);
                logger.info("找到补料中的配置，configId: {}, 当前状态: {}", wmsConfigInfo.getConfigId(), wmsConfigInfo.getSupplyStatus());
            } else {
                logger.info("未找到补料中的配置，查找待补料状态配置");
                // 查找待补料状态的配置
                wmsConfigInfo.setSupplyStatus(BusinessConstants.SUPPLY_STATUS_1);
                wmsConfigInfoList = wmsConfigInfoMapper.selectWmsConfigInfoList(wmsConfigInfo);

                if(wmsConfigInfoList != null && wmsConfigInfoList.size() > 0) {
                    wmsConfigInfo = wmsConfigInfoList.get(0);
                    logger.info("找到待补料状态的配置，configId: {}, 当前状态: {}", wmsConfigInfo.getConfigId(), wmsConfigInfo.getSupplyStatus());
                } else {
                    logger.warn("没有找到任何相关配置，D600=2但数据库中没有对应的配置记录");
                    return; // 如果没有找到配置，直接返回
                }
            }

            //独立缓存库补料
            WmsConfigSupply wmsConfigSupply = new WmsConfigSupply();
            wmsConfigSupply.setConfigId(wmsConfigInfo.getConfigId());
            wmsConfigSupply.setConfigStatus(BusinessConstants.TASK_STATUS_2);
            List<WmsConfigSupply> wmsConfigSupplyList = wmsConfigSupplyMapper.selectWmsConfigSupplyList(wmsConfigSupply);

            if(wmsConfigSupplyList.size() > 0) {
                wmsConfigSupply = wmsConfigSupplyList.get(0);
                wmsConfigSupply.setConfigStatus(BusinessConstants.TASK_STATUS_4);//单笔补料完成
                wmsConfigSupply.setEndTime(new Date());
                wmsConfigSupply.setUpdateTime(new Date());
                int updateResult = wmsConfigSupplyMapper.updateWmsConfigSupply(wmsConfigSupply);
                if(updateResult > 0) {
                    logger.info("补料任务完成，configSupplyId: {}", wmsConfigSupply.getId());
                } else {
                    logger.error("更新补料任务状态失败，configSupplyId: {}", wmsConfigSupply.getId());
                }
            }

            // 检查是否所有补料任务都已完成
            WmsConfigSupply checkAllSupply = new WmsConfigSupply();
            checkAllSupply.setConfigId(wmsConfigInfo.getConfigId());
            checkAllSupply.setConfigStatus(BusinessConstants.SUPPLY_STATUS_1); // 检查待补料的任务
            List<WmsConfigSupply> remainingSupplies = wmsConfigSupplyMapper.selectWmsConfigSupplyList(checkAllSupply);

            checkAllSupply.setConfigStatus(BusinessConstants.SUPPLY_STATUS_2); // 检查补料中的任务
            List<WmsConfigSupply> processingSupplies = wmsConfigSupplyMapper.selectWmsConfigSupplyList(checkAllSupply);

            if(remainingSupplies.isEmpty() && processingSupplies.isEmpty()) {
                // 所有补料任务都已完成，状态应该变为完成(5)
                try {
                    modbusTcpService.writeHoldingRegister(slaveId, 600, 0);//缓存库补料完成
                    logger.info("所有补料任务完成，D600写入0");
                } catch (ModbusTransportException e) {
                    logger.error("写入D600=0失败", e);
                }

                wmsConfigInfo.setSupplyStatus(BusinessConstants.SUPPLY_STATUS_5); // 补料结束
                wmsConfigInfo.setUpdateTime(new Date());
                int updateResult = wmsConfigInfoMapper.updateWmsConfigInfo(wmsConfigInfo);
                if(updateResult > 0) {
                    logger.info("配置状态更新为补料结束(5)成功，configId: {}", wmsConfigInfo.getConfigId());
                } else {
                    logger.error("更新配置状态失败，configId: {}", wmsConfigInfo.getConfigId());
                }
            } else {
                // 还有补料任务在进行中，继续启动补料
                wmsConfigInfoServiceImpl.startConfigSupply(wmsConfigInfo);
            }
            return;
        } else {
            logger.info("D600={}，执行常规入料逻辑", address600V);
        }


//新改的业务逻辑，待验证
        WmsConfigSub wmsConfigSubQuery = new WmsConfigSub();
        wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_CONFIGING);
        List<WmsConfigSub> wmsConfigSubList = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
        if(wmsConfigSubList != null && wmsConfigSubList.size() > 0) {
            WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
            wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_4);
            List<WmsTaskInfo> wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
            if (wmsTaskInfoList.size() > 0) {
                wmsTaskInfo = wmsTaskInfoList.get(0);
                wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_4);
                wmsTaskInfo.setUpdateTime(new Date());
                logger.info("非满盒补料入库" + wmsTaskInfo.getTaskId());
                wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
            }

            feedingMixV();
        } else {
            wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_PRE);
            wmsConfigSubList = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
            if(wmsConfigSubList != null && wmsConfigSubList.size() > 0) {
                WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
                wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_4);
                List<WmsTaskInfo> wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
                if (wmsTaskInfoList.size() > 0) {
                    wmsTaskInfo = wmsTaskInfoList.get(0);
                    wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_4);
                    wmsTaskInfo.setUpdateTime(new Date());
                    logger.info("非满盒补料入库" + wmsTaskInfo.getTaskId());
                    wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
                }

                feedingMixV();
            } else {
                wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_UNCONFIG);
                wmsConfigSubList = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
                if(wmsConfigSubList != null && wmsConfigSubList.size() > 0) {
                    //增加整盒补料逻辑     20250709
                    WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
                    wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                    wmsTaskInfo.setFullType(BusinessConstants.FULL_TYPE_FULL);
                    List<WmsTaskInfo> taskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
                    if (null != taskInfos && taskInfos.size() > 0) {
                        WmsTaskInfo wmsTaskInfo1 = taskInfos.get(0);
                        wmsTaskInfo1.setTaskStatus(BusinessConstants.TASK_STATUS_4);
                        wmsTaskInfo1.setUpdateTime(new Date());
                        logger.info("整盒补料入库" + wmsTaskInfo1.getTaskId());
                        wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo1);
                    }

                    feedingFull();
                }
            }
        }

/*
        wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_UNCONFIG);
        wmsConfigSubList = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSubQuery);
        if(wmsConfigSubList != null && wmsConfigSubList.size() > 0) {
            //增加整盒补料逻辑     20250709
            WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
            wmsTaskInfo.setFullType(BusinessConstants.FULL_TYPE_FULL);
            List<WmsTaskInfo> taskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
            if (null != taskInfos && taskInfos.size() > 0) {
                WmsTaskInfo wmsTaskInfo1 = taskInfos.get(0);
                wmsTaskInfo1.setTaskStatus(BusinessConstants.TASK_STATUS_4);
                wmsTaskInfo1.setUpdateTime(new Date());
                logger.info("整盒补料入库" + wmsTaskInfo1.getTaskId());
                wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo1);
            }

            feedingFull();
        } else {
            WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
            wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_4);
            List<WmsTaskInfo> wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
            if (wmsTaskInfoList.size() > 0) {
                wmsTaskInfo = wmsTaskInfoList.get(0);
                wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_4);
                wmsTaskInfo.setUpdateTime(new Date());
                logger.info("非满盒补料入库" + wmsTaskInfo.getTaskId());
                wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
            }

            feedingMixV();
        }
*/

    }

    public void process557V() {
        WmsCellInfo wmsCellInfo = new WmsCellInfo();
        wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_2);
        List<WmsCellInfo> list = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfo);
        if(list != null && list.size() > 0) {
            //后库来料入库
            for (int i = 0; i < list.size(); i++) {
                logger.info("后库来料入库 - 废弃");
                wmsCellInfo = list.get(i);
                wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_3);
                wmsCellInfo.setUpdateTime(new Date());
                wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfo);
            }

            WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
            wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_4);
            List<WmsTaskInfo> wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
            if (wmsTaskInfoList.size() > 0) {
                wmsTaskInfo = wmsTaskInfoList.get(0);
                wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_4);
                wmsTaskInfo.setUpdateTime(new Date());
                wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
            }
        } else {
            //配针机回流入库
            WmsNeedleCache wmsNeedleCache = new WmsNeedleCache();
            wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_3);
            List<WmsNeedleCache> wmsNeedleCaches = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCache);
            for (int i = 0; i < wmsNeedleCaches.size(); i++) {
                wmsNeedleCache = wmsNeedleCaches.get(i);
                wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_1);
                wmsNeedleCache.setUpdateTime(new Date());
                wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCache);
            }

            WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
            wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_2);
            List<WmsTaskInfo> wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
            if (wmsTaskInfoList.size() > 0) {
                wmsTaskInfo = wmsTaskInfoList.get(0);
                wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_4);
                wmsTaskInfo.setUpdateTime(new Date());
                wmsTaskInfoMapper.updateWmsTaskInfo(wmsTaskInfo);
            }
        }

        feedingMixV();
    }


    private int get501Value() {
        return getIntCache(GlobalVariable.PLC_501_VALUE);
    }

    private int get502Value() {
        return getIntCache(GlobalVariable.PLC_502_VALUE);
    }

    private int getTray() {
        return getIntCache(GlobalVariable.CONFIG_TRAY);
    }

    private int getIntCache(String key) {
        return redisCache.getCacheObject(key) == null ? 0 : (int) redisCache.getCacheObject(key);
    }

    /**
     * 手动触发缓存库补料失败回滚
     * 用于任务重新初始化或异常恢复时手动清理状态
     */
    public void manualRollbackCacheSupply() {
        logger.info("手动触发缓存库补料失败回滚操作");
        rollbackCacheSupplyFailure();
    }

    /**
     * 手动触发缓存库出料失败回滚
     * 用于任务重新初始化或异常恢复时手动清理状态
     */
    public void manualRollbackCacheDelivery() {
        logger.info("手动触发缓存库出料失败回滚操作");
        rollbackCacheDeliveryFailure();
    }

    /**
     * 缓存库补料失败回滚 - 将入库中状态的缓存库位回滚为空闲状态
     * 当机械手未能成功将料盒放入缓存库时调用此方法
     */
    public void rollbackCacheSupplyFailure() {
        logger.info("开始执行缓存库补料失败回滚操作...");
        long startTime = System.currentTimeMillis();

        try {
            // 查找所有处于"入库中"状态的缓存库位
            WmsCellInfo cellQuery = new WmsCellInfo();
            cellQuery.setCellStatus(BusinessConstants.CELL_STATUS_2); // 入库中状态
            List<WmsCellInfo> cellsInProgress = wmsCellInfoMapper.selectWmsCellInfoList(cellQuery);

            if (cellsInProgress != null && cellsInProgress.size() > 0) {
                logger.info("发现 {} 个处于入库中状态的缓存库位，开始回滚", cellsInProgress.size());

                int rollbackCount = 0;
                for (WmsCellInfo cell : cellsInProgress) {
                    // 清空库位信息并设置为空闲状态
                    cell.setCellStatus(BusinessConstants.CELL_STATUS_1); // 设为空闲
                    cell.setBoxCode(null);
                    cell.setDrillInfo(null);
                    cell.setDrillCount(0L);
                    cell.setDrillSize(null);
                    cell.setDrillType(null);
                    cell.setDrillEdge(null);
                    cell.setDrillFactory(null);
                    cell.setDrillGrindCount(null);
                    cell.setUpdateTime(new Date());

                    // 更新数据库
                    int updateResult = wmsCellInfoMapper.updateWmsCellInfo(cell);
                    if (updateResult > 0) {
                        rollbackCount++;
                        logger.info("缓存库位 {} 状态已从入库中回滚为空闲", cell.getCellId());
                    } else {
                        logger.error("缓存库位 {} 状态回滚失败", cell.getCellId());
                    }
                }

                logger.info("缓存库补料失败回滚完成，成功回滚 {} 个库位", rollbackCount);
            } else {
                logger.info("未发现需要回滚的缓存库位（入库中状态）");
            }

            // 同时回滚相关的任务状态
            rollbackRelatedTasks();

        } catch (Exception e) {
            logger.error("缓存库补料失败回滚过程中发生异常", e);
            throw new RuntimeException("缓存库状态回滚失败: " + e.getMessage());
        } finally {
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            logger.info("缓存库补料失败回滚操作耗时 {} ms", duration);
        }
    }

    /**
     * 回滚相关的任务状态
     * 将相关的补料任务状态重置为待处理
     */
    private void rollbackRelatedTasks() {
        logger.info("开始回滚相关任务状态...");

        try {
            // 查找所有处理中的补料任务（类型4：后库钻针补料入缓存库）
            WmsTaskInfo taskQuery = new WmsTaskInfo();
            taskQuery.setTaskType(BusinessConstants.TASK_TYPE_4);
            taskQuery.setTaskStatus(BusinessConstants.TASK_STATUS_2); // 处理中状态
            List<WmsTaskInfo> tasksInProgress = wmsTaskInfoMapper.selectWmsTaskInfoList(taskQuery);

            if (tasksInProgress != null && tasksInProgress.size() > 0) {
                logger.info("发现 {} 个处理中的补料任务，开始状态回滚", tasksInProgress.size());

                int taskRollbackCount = 0;
                for (WmsTaskInfo task : tasksInProgress) {
                    // 将任务状态重置为待处理
                    task.setTaskStatus(BusinessConstants.TASK_STATUS_1);
                    task.setCellId(null); // 清空绑定的库位ID
                    task.setUpdateTime(new Date());

                    int updateResult = wmsTaskInfoMapper.updateWmsTaskInfo(task);
                    if (updateResult > 0) {
                        taskRollbackCount++;
                        logger.info("补料任务 {} 状态已从处理中回滚为待处理", task.getTaskId());
                    } else {
                        logger.error("补料任务 {} 状态回滚失败", task.getTaskId());
                    }
                }

                logger.info("任务状态回滚完成，成功回滚 {} 个任务", taskRollbackCount);
            } else {
                logger.info("未发现需要回滚的补料任务");
            }

        } catch (Exception e) {
            logger.error("回滚相关任务状态时发生异常", e);
        }
    }

    /**
     * 缓存库出料失败回滚 - 将出库中状态的缓存库位回滚为有货状态
     * 当机械手未能成功从缓存库抓出料盒时调用此方法
     */
    public void rollbackCacheDeliveryFailure() {
        logger.info("开始执行缓存库出料失败回滚操作...");
        long startTime = System.currentTimeMillis();

        try {
            // 查找所有处于"出库中"状态的缓存库位
            WmsCellInfo cellQuery = new WmsCellInfo();
            cellQuery.setCellStatus(BusinessConstants.CELL_STATUS_4); // 出库中状态
            List<WmsCellInfo> cellsInProgress = wmsCellInfoMapper.selectWmsCellInfoList(cellQuery);

            if (cellsInProgress != null && cellsInProgress.size() > 0) {
                logger.info("发现 {} 个处于出库中状态的缓存库位，开始回滚", cellsInProgress.size());

                int rollbackCount = 0;
                for (WmsCellInfo cell : cellsInProgress) {
                    // 将状态从出库中回滚为有货，保留原有料盒信息
                    cell.setCellStatus(BusinessConstants.CELL_STATUS_3); // 设为有货
                    cell.setUpdateTime(new Date());
                    // 注意：不清空料盒信息，因为料盒实际上还在库位中

                    // 更新数据库
                    int updateResult = wmsCellInfoMapper.updateWmsCellInfo(cell);
                    if (updateResult > 0) {
                        rollbackCount++;
                        logger.info("缓存库位 {} 状态已从出库中回滚为有货，料号: {}",
                                cell.getCellId(), cell.getDrillInfo());
                    } else {
                        logger.error("缓存库位 {} 状态回滚失败", cell.getCellId());
                    }
                }

                logger.info("缓存库出料失败回滚完成，成功回滚 {} 个库位", rollbackCount);
            } else {
                logger.info("未发现需要回滚的缓存库位（出库中状态）");
            }

            // 同时回滚相关的出库任务状态
            rollbackRelatedDeliveryTasks();

        } catch (Exception e) {
            logger.error("缓存库出料失败回滚过程中发生异常", e);
            throw new RuntimeException("缓存库出料状态回滚失败: " + e.getMessage());
        } finally {
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            logger.info("缓存库出料失败回滚操作耗时 {} ms", duration);
        }
    }

    /**
     * 回滚相关的出库任务状态
     * 将相关的出库任务状态重置为待处理
     */
    private void rollbackRelatedDeliveryTasks() {
        logger.info("开始回滚相关出库任务状态...");

        try {
            // 查找所有处理中的出库任务（类型1：缓存库满盒出库配针机）
            WmsTaskInfo taskQuery = new WmsTaskInfo();
            taskQuery.setTaskType(BusinessConstants.TASK_TYPE_1);
            taskQuery.setTaskStatus(BusinessConstants.TASK_STATUS_2); // 处理中状态
            List<WmsTaskInfo> tasksInProgress = wmsTaskInfoMapper.selectWmsTaskInfoList(taskQuery);

            if (tasksInProgress != null && tasksInProgress.size() > 0) {
                logger.info("发现 {} 个处理中的出库任务，开始状态回滚", tasksInProgress.size());

                int taskRollbackCount = 0;
                for (WmsTaskInfo task : tasksInProgress) {
                    // 将任务状态重置为待处理
                    task.setTaskStatus(BusinessConstants.TASK_STATUS_1);
                    task.setCellId(null); // 清空绑定的库位ID
                    task.setUpdateTime(new Date());

                    int updateResult = wmsTaskInfoMapper.updateWmsTaskInfo(task);
                    if (updateResult > 0) {
                        taskRollbackCount++;
                        logger.info("出库任务 {} 状态已从处理中回滚为待处理，料号: {}",
                                task.getTaskId(), task.getDrillInfo());
                    } else {
                        logger.error("出库任务 {} 状态回滚失败", task.getTaskId());
                    }
                }

                logger.info("出库任务状态回滚完成，成功回滚 {} 个任务", taskRollbackCount);
            } else {
                logger.info("未发现需要回滚的出库任务");
            }

        } catch (Exception e) {
            logger.error("回滚相关出库任务状态时发生异常", e);
        }
    }

    /**
     * 检查并回滚卡住的缓存库位
     * 检查长时间处于入库中或出库中状态的库位，可能是操作失败导致的
     */
    private void checkAndRollbackStuckedCells() {
        logger.info("检查是否存在卡住的缓存库位...");

        try {
            Date currentTime = new Date();
            long timeoutThreshold = 5 * 60 * 1000; // 5分钟超时阈值

            // 检查处于"入库中"状态的缓存库位
            checkAndRollbackStuckedSupplyCells(currentTime, timeoutThreshold);

            // 检查处于"出库中"状态的缓存库位
            checkAndRollbackStuckedDeliveryCells(currentTime, timeoutThreshold);

        } catch (Exception e) {
            logger.error("检查卡住库位时发生异常", e);
        }
    }

    /**
     * 检查并回滚卡住的入库中状态库位
     */
    private void checkAndRollbackStuckedSupplyCells(Date currentTime, long timeoutThreshold) {
        try {
            // 查找所有处于"入库中"状态的缓存库位
            WmsCellInfo cellQuery = new WmsCellInfo();
            cellQuery.setCellStatus(BusinessConstants.CELL_STATUS_2); // 入库中状态
            List<WmsCellInfo> cellsInProgress = wmsCellInfoMapper.selectWmsCellInfoList(cellQuery);

            if (cellsInProgress != null && cellsInProgress.size() > 0) {
                boolean foundStuckedCells = false;
                for (WmsCellInfo cell : cellsInProgress) {
                    if (cell.getUpdateTime() != null) {
                        long timeDiff = currentTime.getTime() - cell.getUpdateTime().getTime();
                        if (timeDiff > timeoutThreshold) {
                            logger.warn("发现超时的入库中状态库位: {} (超时 {} 秒)",
                                    cell.getCellId(), timeDiff / 1000);
                            foundStuckedCells = true;
                        }
                    }
                }

                if (foundStuckedCells) {
                    logger.info("检测到卡住的入库中库位，执行补料失败回滚操作");
                    rollbackCacheSupplyFailure();
                } else {
                    logger.debug("所有入库中状态的库位都在正常时间范围内");
                }
            } else {
                logger.debug("未发现处于入库中状态的库位");
            }
        } catch (Exception e) {
            logger.error("检查入库中状态库位时发生异常", e);
        }
    }

    /**
     * 检查并回滚卡住的出库中状态库位
     */
    private void checkAndRollbackStuckedDeliveryCells(Date currentTime, long timeoutThreshold) {
        try {
            // 查找所有处于"出库中"状态的缓存库位
            WmsCellInfo cellQuery = new WmsCellInfo();
            cellQuery.setCellStatus(BusinessConstants.CELL_STATUS_4); // 出库中状态
            List<WmsCellInfo> cellsInProgress = wmsCellInfoMapper.selectWmsCellInfoList(cellQuery);

            if (cellsInProgress != null && cellsInProgress.size() > 0) {
                boolean foundStuckedCells = false;
                for (WmsCellInfo cell : cellsInProgress) {
                    if (cell.getUpdateTime() != null) {
                        long timeDiff = currentTime.getTime() - cell.getUpdateTime().getTime();
                        if (timeDiff > timeoutThreshold) {
                            logger.warn("发现超时的出库中状态库位: {} (超时 {} 秒), 料号: {}",
                                    cell.getCellId(), timeDiff / 1000, cell.getDrillInfo());
                            foundStuckedCells = true;
                        }
                    }
                }

                if (foundStuckedCells) {
                    logger.info("检测到卡住的出库中库位，执行出料失败回滚操作");
                    rollbackCacheDeliveryFailure();
                } else {
                    logger.debug("所有出库中状态的库位都在正常时间范围内");
                }
            } else {
                logger.debug("未发现处于出库中状态的库位");
            }
        } catch (Exception e) {
            logger.error("检查出库中状态库位时发生异常", e);
        }
    }

    private WmsNeedleCache calcSupplyNeedleid(WmsConfigSub wmsConfigSub, String drillInfo) {
        WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
        wmsTaskInfo.setTaskType(BusinessConstants.TASK_TYPE_3);
        wmsTaskInfo.setFullType(BusinessConstants.FULL_TYPE_MIX);
        List<WmsTaskInfo> wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
        int total = wmsTaskInfoList.size();

        wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_4);
        wmsTaskInfoList = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
        int needleidCount = 0;
        for (int i = 0; i < wmsTaskInfoList.size(); i++) {
            WmsTaskInfo wmsTaskInfo1 = wmsTaskInfoList.get(i);
            needleidCount = needleidCount + wmsTaskInfo1.getBoxId().intValue();
        }
        int finished = wmsTaskInfoList.size();

        int quotient = total / 2;

        // 【修改】优先查找空闲位置，避免混料
        logger.info("优先查找空闲位置进行补料，料号: {}", drillInfo);
        WmsNeedleCache wmsNeedleCache = new WmsNeedleCache();
        wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_1);
        List<WmsNeedleCache> wmsNeedleCaches = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCache);

        // 双重检查：验证PLC实际状态，确保真正空闲
        List<WmsNeedleCache> actuallyEmptyPositions = new ArrayList<>();
        for (WmsNeedleCache cache : wmsNeedleCaches) {
            try {
                // 读取PLC实际状态 (配针机位置从4700开始，needleId从1开始)
                int plcAddress = 4699 + cache.getNeedleId().intValue();
                int actualCount = modbusTcpService.readHoldingRegister(slaveId, plcAddress);

                if (actualCount == 0) {
                    // PLC中确实为空，加入可用位置列表
                    actuallyEmptyPositions.add(cache);
                    logger.info("配针机位置 {} 确认为空闲，PLC数量: {}", cache.getNeedleId(), actualCount);
                } else {
                    // PLC中有料，但数据库显示空闲，记录状态不一致
                    logger.warn("状态不一致！配针机位置 {} 数据库显示空闲但PLC有料，数量: {}", cache.getNeedleId(), actualCount);
                    // 更新数据库状态以保持一致性
                    cache.setStatus(BusinessConstants.NEEDLE_STATUS_2);
                    cache.setDrillCount((long)actualCount);
                    wmsNeedleCacheMapper.updateWmsNeedleCache(cache);
                }
            } catch (Exception e) {
                logger.error("读取配针机位置 {} PLC状态时发生异常: {}", cache.getNeedleId(), e.getMessage());
                // 读取异常时，为安全起见不使用该位置
            }
        }

        if(actuallyEmptyPositions.size() > 0) {
            logger.info("找到 {} 个真正空闲的配针机位置", actuallyEmptyPositions.size());

            if(finished >= quotient) {//补料过半

                //替换下方逻辑  20251018
                if(getTray() == 1) {
                    for (int i = 0; i < actuallyEmptyPositions.size(); i++) {
                        WmsNeedleCache wmsNeedleCache1 = actuallyEmptyPositions.get(i);
                        if(wmsNeedleCache1.getNeedleId() > 42) {
                            logger.info("选择右侧配针机位置: {} 进行补料", wmsNeedleCache1.getNeedleId());
                            return wmsNeedleCache1;
                        }
                    }
                } else {
                    for (int i = 0; i < actuallyEmptyPositions.size(); i++) {
                        WmsNeedleCache wmsNeedleCache1 = actuallyEmptyPositions.get(i);
                        if(wmsNeedleCache1.getNeedleId() <= 42) {
                            logger.info("选择左侧配针机位置: {} 进行补料", wmsNeedleCache1.getNeedleId());
                            return wmsNeedleCache1;
                        }
                    }
                }
/*
                if(needleidCount < 42) {//左补料，切右补料
                    for (int i = 0; i < actuallyEmptyPositions.size(); i++) {
                        WmsNeedleCache wmsNeedleCache1 = actuallyEmptyPositions.get(i);
                        if(wmsNeedleCache1.getNeedleId() > 42) {
                            logger.info("选择右侧配针机位置: {}", wmsNeedleCache1.getNeedleId());
                            return wmsNeedleCache1;
                        }
                    }
                }
*/
            }
            logger.info("选择配针机位置: {}", actuallyEmptyPositions.get(0).getNeedleId());
            return actuallyEmptyPositions.get(0);
        } else {
            logger.warn("没有找到真正空闲的配针机位置，暂停送料");
            return null;
        }
    }
}
